#!/local/usr/bin/python

import os, sys
import cnl2mc_console

class Validator:
    
    def __init__(self):
        self.console = cnl2mc_console.Console()
    def config(self, configFile):
        self.console.config(configFile)
    
    def splitIdIntoTestingFoldsDict(self, dataNodeDict, codeName, n = 10):
        testingIdFoldsDict = {}
        for i in range(n):
            testingIdFoldsDict[i] = []            
        ids = dataNodeDict.keys()
        import random
        random.seed(1)
        rand1 = random.Random()
        rand2 = random.Random()
        for id in ids:
            if codeName in dataNodeDict[id].classFreqDist:
                i = rand1.randint(0,n-1)                
            else:
                i = rand2.randint(0,n-1)
            testingIdFoldsDict[i].append(id)
        for fold in testingIdFoldsDict.values():
            fold.sort()
        return testingIdFoldsDict
            
    def getTestingAndTrainingFold(self, dataNodeDict, testingIdFold):
        testingNodesDict = {}
        trainingNodesDict = dataNodeDict.copy()
        for key in testingIdFold:
            testingNodesDict[key] = trainingNodesDict.pop(key)
        return (testingNodesDict, trainingNodesDict)
    
    def main(self):
        console = self.console
        sqlConfigDict = console.xmlConf.getSqlConfig()
        dataNodeDict = console.readTrainingDataNodeDict(sqlConfigDict)                                            
        console.preprocess(dataNodeDict)
                                      
        focusedClassesFilename = console.xmlConf.getFocusedClassesFilename()            
        if os.path.exists(focusedClassesFilename):
            focusedClassList = open(focusedClassesFilename, 'rU').read().split()
        else:
            focusedClassList = console.globalClassFreqDist.keys()
        
        codeQuantity = len(focusedClassList)
        processedCodeAmount = 0
        for pickedClass in focusedClassList:
            testingFoldsDict = self.splitIdIntoTestingFoldsDict(dataNodeDict, pickedClass, n = 10)                       
            for (k, testingFold) in testingFoldsDict.items():
                (testingNodeDict, trainingNodeDict) = self.getTestingAndTrainingFold(dataNodeDict, testingFold)
                
                dirname = console.xmlConf.getGenerateFilePath()           
                basename = os.path.basename(console.xmlConf.getFeatureMatrixFileName())
                outputPath = os.path.join(dirname,str(k))
                
                trainingFeatureMatrixFileName = os.path.join(outputPath, "train_%s_%s"%(pickedClass,basename))
                testingFeatureMatrixFileName = os.path.join(outputPath, "test_%s_%s"%(pickedClass,basename))
                
                indexMethod = console.xmlConf.getIndexMethod()
                indexer = console.instFact.getNewIndexer(indexMethod)
                
                attachment = console.getIndexAttachment(indexer, trainingNodeDict)
                
                console.indexInFile(trainingFeatureMatrixFileName, trainingNodeDict, indexer, attachment)                
                console.indexInFile(testingFeatureMatrixFileName, testingNodeDict, indexer, attachment)  
                
                
                toFileType = console.xmlConf.getGenerateFileType()
                            
                reduceDimMethodType = console.xmlConf.getReduceDimMethodType()
                reduceDimMethodName = console.xmlConf.getReduceDimMethodName()
                freqThreshold = console.xmlConf.getFrequencyThreshold()
                IgThreshold = console.xmlConf.getInfoGainThreshold()

                binaryClassList = [pickedClass, '-1']
                reducedDimWordList = console.reduceDim(trainingNodeDict, binaryClassList, reduceDimMethodType, reduceDimMethodName, freqThreshold, IgThreshold)
                trainingFilename = "train_%s"%pickedClass
                # add IG_Reducing here. And a arff attributes parser --> reducedDimWordList
                testingFilename =  "test_%s"%pickedClass
                console.generateVectorFile(trainingNodeDict, trainingFeatureMatrixFileName, reducedDimWordList, toFileType, binaryClassList, outputPath, trainingFilename)
                console.generateVectorFile(testingNodeDict, testingFeatureMatrixFileName, reducedDimWordList, toFileType, binaryClassList, outputPath, testingFilename)
                              
                os.remove(trainingFeatureMatrixFileName)
                os.remove(testingFeatureMatrixFileName)
            processedCodeAmount += 1
            print " %d codes in process: %d code(s) done, %d file(s) left.\n" \
                    %(codeQuantity, processedCodeAmount, codeQuantity - processedCodeAmount)  
            """ """
if __name__ == '__main__':    
    validator = Validator()
    configFile = sys.argv[1]
    validator.config(configFile)
    
    validator.main()
    
    
    
    
    
    
    
    
    
    
    